using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using C1.C1Report;
using Microsoft.Office.Interop.Excel;
using PCSUtils.Utils;
using System.Data;
using System.Data.OleDb;
using System.Reflection;
using C1.Win.C1Preview;
using C1PrintPreviewDialog = C1.Win.C1Preview.C1PrintPreviewDialog;
using DataTable = System.Data.DataTable;

namespace TienDoSanXuatMaHang
{
	[Serializable]
	public class TienDoSanXuatMaHang : MarshalByRefObject, IDynamicReport
	{
		public TienDoSanXuatMaHang()
		{
		}

		private string mConnectionString;
		private ReportBuilder mReportBuilder;
		private C1PrintPreviewControl mReportViewer;
		private object mResult;

		/// <summary>
		/// ConnectionString, provide for the Dynamic Report
		/// ALlow Dynamic Report to access the DataBase of PCS
		/// </summary>
		public string PCSConnectionString
		{
			get { return mConnectionString; }
			set { mConnectionString = value; }
		}

		/// <summary>
		/// Report Builder Utility Object
		/// Dynamic Report can use this object to render, modify, layout the report
		/// </summary>
		public ReportBuilder PCSReportBuilder
		{
			get { return mReportBuilder; }
			set { mReportBuilder = value; }
		}

		/// <summary>
		/// ReportViewer Object, provide for the DynamicReport, 
		/// allow Dynamic Report to manipulate with the REportViewer, 
		/// modify the report after rendered if needed
		/// </summary>
        public C1PrintPreviewControl PCSReportViewer
		{
			get { return mReportViewer; }
			set { mReportViewer = value; }
		}

		/// <summary>
		/// Store other result if any. Ussually we store return DataTable here to display on the ReportViewer Form's Grid
		/// </summary>
		public object Result
		{
			get { return mResult; }
			set { mResult = value; }
		}

		private bool mUseReportViewerRenderEngine = false;

		/// <summary>
		/// Notify PCS whether the rendering report process is run by
		/// this IDynamicReport or the ReportViewer Engine (in the ReportViewer form)
		/// </summary>
		public bool UseReportViewerRenderEngine
		{
			get { return mUseReportViewerRenderEngine; }
			set { mUseReportViewerRenderEngine = value; }
		}

		private string mstrReportDefinitionFolder = string.Empty;
		/// <summary>
		/// Inform External Process where to find out the ReportLayout	 ( the PCS' ReportDefinition Folder Path )
		/// </summary>				
		public string ReportDefinitionFolder
		{
			get { return mstrReportDefinitionFolder; }
			set { mstrReportDefinitionFolder = value; }
		}


		private string mstrReportLayoutFile = string.Empty;		
		/// <summary>
		/// Inform External Process about the Layout file
		/// in which PCS instruct to use
		/// (PCS will assign this property while ReportViewer Form execute,
		/// ReportVIewer form will use the layout file in the report config entry to put in this property)
		/// </summary>		
		public string ReportLayoutFile
		{
			get 
			{
				return mstrReportLayoutFile;
			}
			set
			{
				mstrReportLayoutFile = value;
			}
		}


		public object Invoke(string pstrMethod, object[] pobjParameters)
		{
			return this.GetType().InvokeMember(pstrMethod, BindingFlags.InvokeMethod, null, this, pobjParameters);
		}

		public DataTable ExecuteReport(string pstrSaleOrderDetailID)
		{
			DataTable dtbReportData = GetReportData(pstrSaleOrderDetailID);
			
			C1Report rptReport = new C1Report();
			if (mstrReportLayoutFile == null || mstrReportLayoutFile.Length == 0)
				mstrReportLayoutFile = "TienDoSanXuatMaHang.xml";
			string[] arrstrReportInDefinitionFile = rptReport.GetReportInfo(mstrReportDefinitionFolder + "\\" + mstrReportLayoutFile);
			rptReport.Load(mstrReportDefinitionFolder + "\\" + mstrReportLayoutFile, arrstrReportInDefinitionFile[0]);
			arrstrReportInDefinitionFile = null;
			rptReport.Layout.PaperSize = PaperKind.A4;

            decimal decTotalClosed = 0, decTotalRelease = 0;
            try
            {
                decTotalClosed = Convert.ToDecimal(dtbReportData.Compute("SUM(ProduceTime)", "Status = 3"));
            }
            catch { }
            try
            {
                decTotalRelease = Convert.ToDecimal(dtbReportData.Compute("SUM(ProduceTime)", "Status = 2"));
            }
            catch { }

            if (decTotalClosed + decTotalRelease > 0)
            {
                decimal decClosePercent = Math.Round((decTotalClosed / (decTotalClosed + decTotalRelease)) * 100, 0);
                decimal decReleasePercent = 100 - decClosePercent;

                string totalClosedText = string.Format("{0}%", decClosePercent);
                string totalReleaseText = string.Format("{0}%", decReleasePercent);

                Field totalClosed = rptReport.Fields["fldTotalClosed"];
                totalClosed.Value = totalClosedText;
                Field totalRelease = rptReport.Fields["fldTotalRelease"];
                totalRelease.Value = totalReleaseText;
            }

			rptReport.DataSource.Recordset = dtbReportData;
			rptReport.Render();
			C1PrintPreviewDialog ppvViewer = new C1PrintPreviewDialog();
			ppvViewer.Text = rptReport.Fields["fldTitle"].Text;
            ppvViewer.NavigationPanelVisible = false;
			ppvViewer.Document = rptReport.Document;
			ppvViewer.Show();

			return dtbReportData;
		}

		private DataTable GetReportData(string pstrSaleOrderDetailID)
		{
			OleDbConnection cn = null;
			try
			{
				cn = new OleDbConnection(mConnectionString);
				DataTable dtbItem = new DataTable();
				string strSql = " SELECT * FROM ((SELECT FGoodsCode, N'Chưa hoàn thành' StatusText, W.Status,"
					+ " P.Code PartNo, P.Description PartName, W.OrderQuantity, SUM(ISNULL(R.LaborRunTime,0)) * W.OrderQuantity ProduceTime,"
					+ " PL.Name ProductionLine"
					+ " FROM PRO_WorkOrderDetail W JOIN SO_SaleOrderDetail S ON W.SaleOrderDetailID = S.SaleOrderDetailID"
					+ " JOIN ITM_Product P ON W.ProductID = P.ProductID"
					+ " JOIN PRO_WORouting R ON W.WorkOrderDetailID = R.WorkOrderDetailID"
					+ " LEFT JOIN PRO_ProductionLine PL ON W.ProductionLineID = PL.ProductionLineID"
					+ " WHERE W.Status = 2"
					+ " AND W.SaleOrderDetailID = " + pstrSaleOrderDetailID
					+ " AND W.WorkOrderDetailID NOT IN (SELECT DISTINCT WorkOrderDetailID FROM PRO_WorkOrderCompletion)"
					+ " GROUP BY FGoodsCode, P.Code, P.Description, W.OrderQuantity, PL.Name, W.Status) "
					+ " UNION ALL"
					+ " (SELECT FGoodsCode, N'Hoàn thành' StatusText, W.Status,"
					+ " NULL PartNo, NULL PartName,"
					+ " SUM(W.OrderQuantity) OrderQuantity, R1.ProduceTime,"
					+ " NULL ProductionLine"
					+ " FROM PRO_WorkOrderDetail W JOIN SO_SaleOrderDetail S ON W.SaleOrderDetailID = S.SaleOrderDetailID"
					+ " JOIN ITM_Product P ON W.ProductID = P.ProductID"
					+ " JOIN (SELECT SUM(ISNULL(LaborRunTime,0) * D.OrderQuantity) ProduceTime, D.SaleOrderDetailID"
					+ " FROM PRO_WORouting R JOIN PRO_WorkOrderDetail D ON R.WorkOrderDetailID = D.WorkOrderDetailID"
					+ " JOIN SO_SaleOrderDetail SD ON D.SaleOrderDetailID = SD.SaleOrderDetailID"
					+ " AND SD.SaleOrderDetailID = " + pstrSaleOrderDetailID
					+ " WHERE D.WorkOrderDetailID IN (SELECT DISTINCT WorkOrderDetailID FROM PRO_WorkOrderCompletion)"
					+ " GROUP BY D.SaleOrderDetailID) R1"
					+ " ON W.SaleOrderDetailID = R1.SaleOrderDetailID"
					+ " WHERE W.Status = 3"
					+ " AND W.SaleOrderDetailID = " + pstrSaleOrderDetailID
					+ " AND W.WorkOrderDetailID IN (SELECT DISTINCT WorkOrderDetailID FROM PRO_WorkOrderCompletion)"
					+ " GROUP BY FGoodsCode, W.Status, R1.ProduceTime)) A"
					+ " ORDER BY A.ProductionLine";
				OleDbDataAdapter odad = new OleDbDataAdapter(strSql, cn);
				odad.Fill(dtbItem);
				return dtbItem;
			}
			finally
			{
				if (cn != null)
					if (cn.State != ConnectionState.Closed)
						cn.Close();
			}
		}
	}
}
